package it.crosato.stage.server.model.phylogeny;

import java.awt.Graphics;

public class ClusterNJ extends Cluster {
	int lab;			// Idienticatore del clister
	int card;			// Il numero di organsimi nel cluster
	ClusterNJ left, right;	// Figli desto sinistro nullo
	double dleft, dright;		// Lunghezza deigli archi fino ai figli
	double[] dmat;                // Distanze ai nodi numerati più bassi o null
	String nome="";

	public ClusterNJ(int lab, double[] dmat, String org) {

		this.lab = lab + 1;
		card = 1;
		this.dmat = dmat;
		nome=org;
	}

	public ClusterNJ(int lab, ClusterNJ left, double dleft,
			ClusterNJ right, double dright, double[] dmat) {

		this.lab = lab + 1;
		this.left = left;   this.dleft  = dleft;
		this.right = right; this.dright = dright;
		card = left.card + right.card;
		this.dmat = dmat;
	}

	public boolean live(){
		return dmat != null;
	}

	public void kill(){
		dmat = null;
	}

	double height() {
		if (left != null && right != null)
			return Math.max(left.height() + dleft, right.height() + dright);
		else
			return 0.0;
	}

	public void print(){
		print(0);
	}

	void print(int n) {
		if (right != null)
			right.print(n + 6);
		if (left != null)
			left.print(n + 6);
	}

	public void draw(Graphics g, int w, int h) {
		double height = height();
		draw(g, w, h, 0, (double)w/card, (double)(h-50)/height, height, 10);
	}

	// Disegna un albero e ritorna la cordinata x della radice

	public int draw(Graphics g, int w, int h, int leftcard,
			double xsc, double ysc, double depth, int fromy) {

		if (left != null && right != null) {	// Nodo interno
			double leftdepth  = depth - dleft;
			double rightdepth = depth - dright;
			int y = (int)(h - 30 - depth * ysc);
			int leftx  = left.draw(g, w, h, leftcard, xsc, ysc, leftdepth, y);
			int rightx = right.draw(g, w, h, leftcard+left.card, xsc, ysc,
					rightdepth, y);
			g.drawLine(leftx, y, rightx, y);
			int x = (leftx + rightx) / 2;
			g.drawLine(x, y, x, fromy);
			g.fillOval(x-4, y-4, 8, 8);
			return x;
		} else {					// Foglia
			int x = (int)((leftcard + 0.5) * xsc);
			int y = (int)(h - 30 - depth * ysc);
			g.drawLine(x, y, x, fromy);
			g.fillOval(x-4, y-4, 8, 8);
			g.drawString(nome, x-5, y+20);
			return x;
		}
	}
}
